(function(window, undefined) {


var Stage = Class.View.Stage;
var Car = Class.View.Car;
var CarColor = Class.View.Car.CarColor;
var Background = Class.View.Background;
var Rock = Class.View.Rock;
var GameStatusView = Class.View.GameStatusView;

var GameInfo = Class.Model.GameInfo;
var GameFPS = Class.Model.GameInfo.GameFPS;
var GameStatus = Class.Model.GameInfo.GameStatus;
var GameEvent = Class.Model.GameInfo.GameEvent;

var GameController = Class({
	name: "GameController",
	parent: "Controller",
	constructor: function() {
		var _gameInfo = new GameInfo();
		var _stage = new Stage();
		var _rocks = [];
		
		var _car = new Car( _gameInfo );
		var _background = new Background( _gameInfo );
		var _infoView = new GameStatusView( _gameInfo );
		
		return {
			__construct: function() {
				console.log( this, "__construct" );
				
				Helper.Timer( this, 1000/GameFPS );
			
				var self = this;
				
				$(window).delegate().keydown( function(e) {
					//console.log( e.which );
					
					switch ( e.which ) {
						 case 37: // Left
						 	self.stop();
						 break;
						 
						 case 39: // Right
						 	self.play();
						 break;
						 
						 case 38: // Up
						 case 32: // Space
						 	self.jump();
						 break;
						 
						 case 40:
						 	self.changeColor();
						 break;
					};
					
					_infoView.update();
					
					return true;
				});
				
				_gameInfo.addEventListener( GameEvent.UpdateStatus, function( status ) {
					_car.update();
					_background.update();
					
					if ( status == GameStatus.GameOver ) {
						self.gameOver();
					};
					
					_infoView.update();
				});
				
				_gameInfo.addEventListener( GameEvent.UpdateDistance, function( distance ) {
				
					_background.flow();
				
					self.flowRocks();
					
					if ( _gameInfo.levelInfo.checkEvent( distance ) ) {
						self.eventRock( distance );
					};
					
					if ( self.hitRocks() ) {
						_gameInfo.gameOver();
					};
					
					_infoView.update();
				});
			},
			
			__tick: function() {
				console.log( this, "__tick", _gameInfo.status() );
				
				_infoView.update();
				
				if ( _gameInfo.isGameOver() == true ) {
				
					this.stopTimer();
				
					return;
				};
				
				_gameInfo.distance( _gameInfo.distance()+1 );
			},
			
			flowRocks: function() {
				var finishRocks = [];
			
				for ( var i=0,l=_rocks.length;i<l;i++ ) {
					var rock = _rocks[i];
					if ( ! rock.flow() ) {
						finishRocks.push( rock );
					};
				};
				
				while( finishRocks.length > 0 ) {
					var rock = finishRocks.shift();
					
					_stage.remove( rock );
					_rocks.remove( rock );
					
					rock.destroy();
				};
				
				if ( _rocks.length == 0 ) { 
					if ( _gameInfo.levelInfo.isClear() ) { 
						_gameInfo.nextLevel();
					};
				};
			},
			
			hitRocks: function() {
				
				for ( var i=0,l=_rocks.length;i<l;i++ ) {
					var rock = _rocks[i];
					if ( rock.hit( _car ) ) {
						return true;
					};
				};
				
				return false;
			},
			
			eventRock: function( distance ) {
				console.log( this, "eventRock" );
				
				var rock = new Rock( _gameInfo, distance );
				_stage.add( rock );
				
				_rocks.push( rock );
			},
			
			gameOver: function() {
				console.log( this, "gameOver" );
				
				this.stopTimer();
				
				_gameInfo.status( GameStatus.GameEnd );
				
				var self = this;
				
				_car.stop( function() {
					
				});
			},
			
			play: function() {
				if ( _gameInfo.isGameOver() == true ) {
					return;				
				};
			
				if ( _gameInfo.isPlaying() == true ) {
					return;
				};
				
				console.log( this, "play" );
				
				this.startTimer();
			
				_gameInfo.status( GameStatus.Warming );
				
				_car.play( function() {
					_gameInfo.status( GameStatus.Playing );
				});
				
				_infoView.update();
			},
			
			stop: function() {
				if ( _gameInfo.isGameOver() == true ) {
					return;				
				};
			
				if ( _gameInfo.isPlaying() == false ) {
					return;
				};
				
				if ( _gameInfo.isJumping() == true ) {
					return;
				};
				
				var self = this;
				
				console.log( this, "stop" );
				
				_gameInfo.status( GameStatus.Stopping );
			
				_car.stop( function() {
					self.stopTimer();
					
					_gameInfo.status( GameStatus.Stopped );
				});
				
				_infoView.update();
			},
			
			jump: function() {
				if ( _gameInfo.isPlaying() == false ) {
					return;
				};
			
				if ( _gameInfo.isJumping() == true ) {
					return;
				};
				
				console.log( this, "jump" );
				
				_gameInfo.status( GameStatus.Jumping );
				
				_car.jump( function() {
					if ( _gameInfo.isPlaying() ) {
						_gameInfo.status( GameStatus.Playing );
					};
				});
				
				_infoView.update();
			},
			
			changeColor: function( color ) {
				console.log( this, "changeColor", color );
			
				if ( color != undefined ) {
					_gameInfo.changeColor( color );
				}
				else if ( _gameInfo.color() == CarColor.Red ) {
			 		_gameInfo.changeColor( CarColor.Blue );
			 	}
			 	else if ( _gameInfo.color() == CarColor.Blue ) {
			 		_gameInfo.changeColor( CarColor.Yellow );
			 	}
			 	else if ( _gameInfo.color() == CarColor.Yellow ) {
			 		_gameInfo.changeColor( CarColor.Red );
			 	};
			 	
			 	_car.update();
			},
			
			setStage: function( $stage ) {
				console.log( this, "setStage" );
			
				_stage.setContainer( $stage );
			},
			
			makeResource: function() {
				console.log( this, "makeResource" );
				
				_stage.add( _background );
				_stage.add( _car );
				_stage.add( _infoView );
				
				_gameInfo.changeColor( CarColor.Red );
				_car.update();
			},
			
			ready: function() {
				console.log( this, "ready" );
				
				while( _rocks.length > 0 ) {
					var rock = _rocks.shift();
					
					_stage.remove( rock );
					_rocks.remove( rock );
					
					rock.destroy();
				};
				
				_gameInfo.ready();
			}
		};
	}
});

Class.Controller.GameController = GameController;

})(window);
